package com.younion.common.base;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.springframework.beans.factory.annotation.Autowired;

import com.google.common.collect.Maps;
import com.opensymphony.xwork2.ActionSupport;
import com.younion.business.IMemberCardService;
import com.younion.business.IMembercardServiceService;
import com.younion.business.IMessageService;
import com.younion.business.IOperateLogService;
import com.younion.business.IProductService;
import com.younion.business.IRegisterUserService;
import com.younion.business.ISendMsgService;
import com.younion.business.IUserService;
import com.younion.business.impl.MemoryCacheManager;
import com.younion.common.constants.SysConstants;
import com.younion.common.constants.TemplateScope;
import com.younion.common.constants.TemplateTargetType;
import com.younion.common.exception.BaseException;
import com.younion.common.paginator.Paginator;
import com.younion.common.paginator.PaginatorUtil;
import com.younion.util.InterfaceRequestValidate;
import com.younion.util.Validator;
import com.younion.util.YounionUtil;
import com.younion.util.json.JsonMapper;
import com.younion.util.spring.SpringContextHolder;
import com.younion.vo.MemberCardVO;
import com.younion.vo.MembercardServiceVO;
import com.younion.vo.MessageVO;
import com.younion.vo.MsgTemplateVO;
import com.younion.vo.OperateLogVO;
import com.younion.vo.ProductVO;
import com.younion.vo.RegisterUserVO;
import com.younion.vo.SendMsgVO;
import com.younion.vo.UserVO;

import cpcns.jhsks.util.MapCollectionUtils;

public class BaseAction extends ActionSupport implements ServletRequestAware, ServletResponseAware {
    private static final long serialVersionUID = 2412172371244144755L;

    public static final String CACHE_KEY = "MEMBERCARD-QUERY-PARAMETERS";

    protected final Logger logger = Logger.getLogger(getClass());

    protected String tipMessage;

    protected HttpServletRequest request;

    protected HttpServletResponse response;

    protected Collection products = null;

    protected Collection users = null;
    protected Collection membercards = null;

    @Autowired
    protected IMemberCardService memberCardService = null;
    @Autowired
    protected IMembercardServiceService membercardServiceService = null;
    @Autowired
    protected IProductService productService = null;

    @Autowired
    protected IUserService userService = null;

    public static final JsonMapper mapper = JsonMapper.buildNormalMapper();

    @Autowired
    protected IOperateLogService operateLogService;

    @Autowired
    private ISendMsgService sendMsgService = null;

    @Autowired
    private IMessageService messageService = null;

    @Autowired
    private IRegisterUserService registerUserService = null;
    
    @Autowired
    protected MemoryCacheManager memoryCacheManager = null;

    protected String searchType;

    protected void sendNotification(MembercardServiceVO service, TemplateTargetType targetType, String content)
            throws Exception {
        if (service == null)
            return;
        String msgType = service.getMsgType();
        if (StringUtils.isBlank(msgType)) {
            msgType = service.getTemplate().getScope();
        }
        if (TemplateScope.MSG.getName().equals(msgType)) {
            getMessageService().save(createMSG(new Date(), service.getTemplate(), service.getMemberCard(), content));
        } else if (TemplateScope.SMS.getName().equals(msgType)) {
            getSendMsgService().save(createSMS(new Date(), service.getTemplate(), service.getMemberCard(), content));
        } else {
            getSendMsgService().save(createSMS(new Date(), service.getTemplate(), service.getMemberCard(), content));
            getMessageService().save(createMSG(new Date(), service.getTemplate(), service.getMemberCard(), content));
        }
    }

    protected MembercardServiceVO retreiveMemberCardService(MemberCardVO card, TemplateTargetType targetType)
            throws BaseException {
        Map params = Maps.newHashMap();
        params.put("memberCardId", card.getId());
        params.put("templateTargetType", targetType.getName());
        Collection services = getMembercardServiceService().getByMap(params);
        MembercardServiceVO service = null;
        if (services.size() <= 0)
            return null;
        for (Iterator<MembercardServiceVO> iterator = services.iterator(); iterator.hasNext();) {
            service = (MembercardServiceVO) iterator.next();
        }
        return service;
    }

    protected SendMsgVO createSMS(Date sendTime, MsgTemplateVO template, MemberCardVO card, String content)
            throws BaseException {
        RegisterUserVO user = getRegisterUserService().getByMemberCard(card);
        return YounionUtil.createSMS(sendTime, template, card, content, user);
    }

    protected MessageVO createMSG(Date sendTime, MsgTemplateVO template, MemberCardVO card, String content)
            throws BaseException {
        RegisterUserVO user = getRegisterUserService().getByMemberCard(card);
        return YounionUtil.createMSG(sendTime, template, card, content, user);
    }

    /**
     * 
     * @return
     */
    public Paginator getPaginator() {
        return PaginatorUtil.getPaginator(ServletActionContext.getRequest());
    }

    /**
     * 
     * @param paginator
     */
    public Paginator getPaginator(int totalCount) {
        Paginator pg = this.getPaginator();
        pg.setTotalCount(totalCount);
        return pg;
    }

    public UserVO getSessionUser() {
        return (UserVO) ServletActionContext.getRequest().getSession().getAttribute(SysConstants.SESSION_USER);
    }

    public void setSessionUser(UserVO user) {
        ServletActionContext.getRequest().getSession().setAttribute(SysConstants.SESSION_USER, user);
    }

    /**
     * 
     * @param paginator
     */
    public void savaPaginator(Paginator paginator) {
        ServletActionContext.getRequest().setAttribute("paginator", paginator);
    }

    public String getTipMessage() {
        return tipMessage;
    }

    public void setTipMessage(String tipMessage) {
        this.tipMessage = tipMessage;
    }

    @Override
    public void setServletRequest(HttpServletRequest request) {
        this.request = request;
    }

    @Override
    public void setServletResponse(HttpServletResponse response) {
        this.response = response;
    }

    /**
     * 对必须的参数进行验证
     * 
     * @param request
     * @param response
     */
    protected boolean checkRequiredParam(HttpServletRequest request, HttpServletResponse response) {
        // 重构: 重复创建对象可以用utility或service代替
        InterfaceRequestValidate validate = new InterfaceRequestValidate();
        boolean isValid = validate.validate(request);
        if (!isValid) {
            response.setCharacterEncoding("UTF-8");
            response.setContentType("text/html;charset=UTF-8");
            PrintWriter writer = null;
            try {
                writer = response.getWriter();
            } catch (IOException e) {
                e.printStackTrace();// 重构: 用logger代替
            }
            String errorReason = validate.getErrorReason();
            errorReason = errorReason == null ? "ERROR" : errorReason;
            writer.write(errorReason);
        }
        return isValid;
    }

    /**
     * 对非空参数进行认证
     * 
     * @param paramName
     * @param paramValue
     * @param response
     * @return
     */
    protected boolean checkNotEmptyParam(String paramName, String paramValue, HttpServletResponse response) {
        boolean isValid = true;
        if (StringUtils.isEmpty(paramValue)) {
            isValid = false;
            response.setCharacterEncoding("UTF-8");
            response.setContentType("text/html;charset=UTF-8");
            PrintWriter writer = null;
            try {
                writer = response.getWriter();
            } catch (IOException e) {
                e.printStackTrace();
            }
            String errorReason = paramName + "参数不合法,必须有值!";
            writer.write(errorReason);
        }
        return isValid;
    }

    /**
     * 对参数是否数字进行判断
     * 
     * @param paramName
     * @param paramValue
     * @param response
     * @return
     */
    protected boolean checkIntegerParam(String paramName, String paramValue, HttpServletResponse response) {
        boolean isValid = true;
        if (!Validator.isInteger(paramValue)) {
            isValid = false;
            response.setCharacterEncoding("UTF-8");
            response.setContentType("text/html;charset=UTF-8");
            PrintWriter writer = null;
            try {
                writer = response.getWriter();
            } catch (IOException e) {
                e.printStackTrace();
            }
            String errorReason = paramName + "值不合法，必须为整数!";
            writer.write(errorReason);
        }
        return isValid;
    }

    /**
     * 输出返回的jsonStr
     * 
     * @param content
     * @param response
     */
    protected void printContent(String content, HttpServletResponse response) {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter writer = null;
        try {
            writer = response.getWriter();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (StringUtils.isEmpty(content)) {
            content = "{}";
        }
        writer.write(content);
    }

    public void setOperateLogService(IOperateLogService operateLogService) {
        this.operateLogService = operateLogService;
    }

    /**
     * 
     * @param type
     *            日志类型：登陆1，查询2，添加3，修改4，删除5
     * @param content
     *            日志内容
     * @param remark
     *            备注
     * @param user
     *            操作用户
     */
    protected void addLog(int type, String content, String remark, UserVO user) {
        if (type == 2)
            return;
        OperateLogVO log = new OperateLogVO();
        log.setType(type);
        log.setContent(content);
        log.setRemark(remark);
        log.setUserId(user.getId());
        try {
            this.operateLogService.save(log);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 
     * @param type
     *            日志类型：登陆1，查询2，添加3，修改4，删除5
     * @param content
     *            日志内容
     * @param remark
     *            备注
     */
    protected void addLog(int type, String content, String remark) {
        if (type == 2)
            return;
        OperateLogVO log = new OperateLogVO();
        log.setType(type);
        log.setContent(content);
        log.setRemark(remark);
        log.setUserId(this.getSessionUser().getId());
        try {
            this.operateLogService.save(log);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public Collection getProducts() {
        if (products == null) {
            try {
                ProductVO product = new ProductVO();
                product.setCustomerVO(getSessionUser().getCustomer());
                Map paramMap = MapCollectionUtils.removeEmptyEntry(PropertyUtils.describe(product));
                products = productService.getByMap(paramMap);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return products;
    }

    public void setProducts(Collection products) {
        this.products = products;
    }

    public Collection getUsers() {
        if (users == null) {
            try {
                users = userService.getByMap(generateParamMap("customerId"));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return users;
    }

    private Map generateParamMap(String key) {
        Map paramMap = Maps.newHashMap();
        if (getSessionUser().getCustomer() != null) {
            paramMap.put(key, getSessionUser().getCustomer().getId());
        }
        return paramMap;
    }

    public void setUsers(Collection users) {
        this.users = users;
    }

    public Collection getMembercards() {
        if (membercards == null) {
            try {
                membercards = memberCardService.getByMap(generateParamMap("customerId"));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return membercards;
    }

    public void setMembercards(Collection membercards) {
        this.membercards = membercards;
    }

    public HttpServletRequest getRequest() {
        return request;
    }

    public void setRequest(HttpServletRequest request) {
        this.request = request;
    }

    public HttpServletResponse getResponse() {
        return response;
    }

    public void setResponse(HttpServletResponse response) {
        this.response = response;
    }

    public IMemberCardService getMemberCardService() {
        if (memberCardService == null) {
            memberCardService = (IMemberCardService) SpringContextHolder.getBean("memberCardService");
        }
        return memberCardService;
    }

    public void setMemberCardService(IMemberCardService memberCardService) {
        this.memberCardService = memberCardService;
    }

    public IProductService getProductService() {
        return productService;
    }

    public void setProductService(IProductService productService) {
        this.productService = productService;
    }

    public IUserService getUserService() {
        return userService;
    }

    public void setUserService(IUserService userService) {
        this.userService = userService;
    }

    public String getSearchType() {
        return searchType;
    }

    public void setSearchType(String searchType) {
        this.searchType = searchType;
    }

    public IOperateLogService getOperateLogService() {
        return operateLogService;
    }

    public ISendMsgService getSendMsgService() {
        if (sendMsgService == null) {
            sendMsgService = (ISendMsgService) SpringContextHolder.getBean("sendMsgService");
        }
        return sendMsgService;
    }

    public void setSendMsgService(ISendMsgService sendMsgService) {
        this.sendMsgService = sendMsgService;
    }

    public IMessageService getMessageService() {
        if (messageService == null) {
            messageService = (IMessageService) SpringContextHolder.getBean("messageService");
        }
        return messageService;
    }

    public void setMessageService(IMessageService messageService) {
        this.messageService = messageService;
    }

    public IRegisterUserService getRegisterUserService() {
        if (registerUserService == null) {
            registerUserService = (IRegisterUserService) SpringContextHolder.getBean("registerUserService");
        }
        return registerUserService;
    }

    public void setRegisterUserService(IRegisterUserService registerUserService) {
        this.registerUserService = registerUserService;
    }

    public IMembercardServiceService getMembercardServiceService() {
        if (membercardServiceService == null) {
            membercardServiceService = (IMembercardServiceService) SpringContextHolder
                    .getBean("membercardServiceService");
        }
        return membercardServiceService;
    }

    public void setMembercardServiceService(IMembercardServiceService membercardServiceService) {
        this.membercardServiceService = membercardServiceService;
    }

    public MemoryCacheManager getMemoryCacheManager() {
        return memoryCacheManager;
    }

    public void setMemoryCacheManager(MemoryCacheManager memoryCacheManager) {
        this.memoryCacheManager = memoryCacheManager;
    }

    
}
